﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Szamlazz.Utils;

namespace Szamlazz.Data
{ 
	/// <summary>
	/// Szemantikai ellenőrzés eredménye
	/// </summary>
	public sealed class ValidationResult
	{
		/// <summary>
		/// Konstruktor
		/// </summary>
		/// <param name="component">Ellenőrzött komponens</param>
		/// <param name="valid">Ellenőrzés sikeres-e</param>
		internal ValidationResult(Validatable component, bool valid)
		{
			this.IsSuccessfull = valid;
			this.Component = component;
		}

		/// <summary>
		/// Komponens amire az ellenőrzés történt
		/// </summary>
		private Validatable Component { get; set; }

		/// <summary>
		/// Ellenőrzés sikeres-e
		/// </summary>
		public bool IsSuccessfull { get; private set; }

		/// <summary>
		/// Ellenőrzés során fellépő hibák
		/// </summary>
		public IEnumerable<Error> Errors { get { return this._Errors; } }
		private List<Error> _Errors = new List<Error>();

		/// <summary>
		/// Hozzáadja az adott hibát a hibalistához
		/// </summary>
		/// <param name="property">Tulajdonság amivel a hiba történt</param>
		/// <param name="reason">Hiba oka</param>
		internal void AddError(string property, ValidationReason reason)
		{
			switch (reason)
			{
				case ValidationReason.Required:
					this._Errors.Add(new Error(3001, string.Format("A {0}->{1} tulajdonság kitöltése kötelező!", this.Component.Component, property)));
					break;
				default:
				case ValidationReason.Invalid:
					this._Errors.Add(new Error(3002, string.Format("A {0}->{1} tulajdonság értéke nem megfelelő", this.Component.Component, property)));
					break;
			}
		}

		/// <summary>
		/// Végrehajtja az ellenőrzést az adott feltételnek megfelelően és sikeresség esetén feldolgozza a megadott ereményt
		/// </summary>
		/// <param name="condition">A feltétel aminek teljesülése esetén az eredmény HIBÁS</param>
		/// <param name="property">A tulajdonság neve, amire a feltétel vonatkozik</param>
		/// <param name="reason">A hiba oka, amit a feltétel indukál</param>
		internal void Evaluate(bool condition, string property, ValidationReason reason)
		{
			if (condition)
			{
				this.IsSuccessfull = false;

				AddError(property, reason);
			}
		}

		/// <summary>
		/// Hiba okok
		/// </summary>
		internal enum ValidationReason
		{
			/// <summary>
			/// Kötelező mező
			/// </summary>
			Required,
			/// <summary>
			/// Hibás mező
			/// </summary>
			Invalid
		}

		/// <summary>
		/// Másik eredmény összevonása ezzel az eredménnyel
		/// </summary>
		/// <param name="other">A másik eredmény amit bemásolunk ide</param>
		internal void Merge(ValidationResult other)
		{
			this.IsSuccessfull &= other.IsSuccessfull;

			foreach (var err in other.Errors)
			{
				this._Errors.Add(err);
			}
		}
	}
}
